#include <pthread.h>
#include <errno.h>

#include <sys/types.h>
#include <sys/socket.h>

#include <log4cxx/logger.h>
#include <log4cxx/xml/domconfigurator.h>

#include <list>
#include <iostream>
#include <string>

/*
#include "MutexLocker.h"
#include "ResourcePool.h"
#include "SocketConnPool.h"
*/
#include "mycrc32.h"

#define THREAD_NUM 100

using std::list;
using std::cout;
using std::endl;
using std::string;

string g_log_conf_file;

static log4cxx::LoggerPtr g_logger = log4cxx::Logger::getLogger("test_sfs_util");
/*
typedef struct _TEST_MUTEX_LOCKER_ROUTINE_ARG {
	pthread_mutex_t mutex;
	list<int> l;
} TEST_MUTEX_LOCKER_ROUTINE_ARG;

void * test_mutex_locker_routine(void * p_arg) {
	LOG4CXX_INFO(g_logger, "enter test mutex locker routine");
       	TEST_MUTEX_LOCKER_ROUTINE_ARG * p = (TEST_MUTEX_LOCKER_ROUTINE_ARG *)p_arg;
	list<int> & the_list = p->l;
	for (int i = 0; i < 30; i++) {
		MutexLocker locker1(&p->mutex);
		locker1.lock();
		the_list.push_back(i);
		LOG4CXX_INFO(g_logger, "push item:" << i << " to list");
	}
	MutexLocker locker2(&p->mutex);
	sleep(1);
	locker2.lock();
	for (list<int>::iterator iter = the_list.begin(); the_list.end() != iter; iter++) {
		LOG4CXX_INFO(g_logger, "iteratate through the list, item:" << *iter)
	}
	return NULL;
}

int test_mutex_locker() {

	TEST_MUTEX_LOCKER_ROUTINE_ARG arg;
	pthread_mutex_init(&arg.mutex, NULL);

	pthread_t threads[THREAD_NUM];
	for (int i = 0; i < THREAD_NUM; i++) {
		pthread_create(&threads[i], NULL, test_mutex_locker_routine, &arg);
	}
	for(int i = 0; i < THREAD_NUM; i++) {
		pthread_join(threads[i], NULL);
	}

	return 1;


}

void * test_resource_pool_routine(void * arg) {
		ResourcePool * res_pool = (ResourcePool *)arg;
		while (true) {
				int index = res_pool->acquire_resource();
				LOG4CXX_INFO(g_logger, "acquire resource index:" << index << ", from resource pool");
				sleep(1);
				res_pool->release_resource(index);
				LOG4CXX_INFO(g_logger, "release resource index:" << index << ", from resource pool");
		}
		return NULL;
}


int test_resource_pool() {
		ResourcePool res_pool;
		res_pool.init(10, 0);
		pthread_t threads[THREAD_NUM];
		for (int i = 0; i < THREAD_NUM; i++) {
				pthread_create(&threads[i], NULL, test_resource_pool_routine, &res_pool);
		}
		for(int i = 0; i < THREAD_NUM; i++) {
				pthread_join(threads[i], NULL);
		}
		return 1;
}
void * test_socket_conn_pool_thread_routine(void * arg) {
	SocketConnPool * pool = (SocketConnPool *)arg;
	while (true) {
		SocketConnPtr ptr;
		int ret = pool->get(ptr);
		if (ret < 0) { cout << "could not get socket conn from pool, ret:" << ret << endl; sleep(1); continue; }
		int fd = ptr.get();
		char buf[1024];
		int r = recv(fd, buf, sizeof(buf), 0);
		if (r >0) { cout << "read " << r << " bytes from socket, content:" << buf << endl; sleep(1); continue; }
		if (0 == r) { cout << "socket closed, fd:" << fd << endl; sleep(1); continue; }
		if (EAGAIN != errno && EINTR != errno) cout << "read error, errno:" << errno << ", fd:" << fd << endl;
		sleep(1);
	}
}

int test_socket_conn_pool() {
	SocketConnPool pool;
	pool.init("127.0.0.1", 3306, 10, 10);
	pthread_t t[10];
	for (int i = 0; i < 10; i++) {
		pthread_create(&t[i], NULL, test_socket_conn_pool_thread_routine, &pool);
	}
	for (int i = 0; i < 10; i++) {
		pthread_join(t[i], NULL);
	}
	return 1;
}

*/
int test_crc32() {
	LOG4CXX_INFO(g_logger, "test crc32 start");
        char buf[1024];
        for (int j = 0; j < 10; j++) {
                for (int i = 0; i < sizeof(buf); i++) buf[i] = j;
                uint32_t crc = get_crc32(buf, sizeof(buf));
                cout << crc << endl;
        }
	LOG4CXX_INFO(g_logger, "test crc32 end");
	return 1;
}


int parse_args(int argc, char * argv[]) {
        char c;
        while(-1 != (c = getopt(argc, argv, "l:"))) {
                switch(c) {
                        case 'l':
                                g_log_conf_file = optarg;
                                break;

                        default:
                                break;
                }
        }
}

int main(int argc, char * argv[]) {
	parse_args(argc, argv);
	log4cxx::xml::DOMConfigurator::configure(g_log_conf_file.c_str());

//	test_mutex_locker();
//	test_resource_pool();
//	test_socket_conn_pool();
	test_crc32();
	return 0;
}
